#include <uapi/linux/ptrace.h>
#include <linux/binfmts.h>
#include <linux/fs.h>
// 联网相关的
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/socket.h>


#define MAY_EXEC		0x00000001
#define MAY_WRITE		0x00000002
#define MAY_READ		0x00000004
#define MAY_APPEND		0x00000008
#define MAY_ACCESS		0x00000010
#define MAY_OPEN		0x00000020
#define MAY_CHDIR		0x00000040


#define CPU_COUNT 4
#define IS_DEBUG 1

// ———————————— 变量声明 ————————————
struct sys_enter_args {
    u64 __unused__;
    long id;
    unsigned long args[6];
};


// ———————————— 主策略库声明 ————————————
#define FILE_NAME_MAX 255
#define MAX_FOLDER_DEPTH 32
#define RELABLE_SYSCALL_NUM 4294967290
#define DOWNGRADE_SYSCALL_NUM 4294967288

// 文件路径 到 read_write_class_id 的映射
struct file_search_key {
    char raw_str[FILE_NAME_MAX];
    int located_directory_id;
};
struct file_search_value {
    int my_id;
    int my_read_write_class_id;
};
BPF_HASH(path_to_read_write_class_id, struct file_search_key, struct file_search_value);
BPF_HASH_OF_MAPS(parent_of_path_to_read_write_class_id, int, "path_to_read_write_class_id", 128);

// ip地址（48字节） 到 read_write_class_id 的映射
struct ip_address {
    char raw_data[48];
};
BPF_HASH(ip_address_to_read_write_class_id, struct ip_address, int);


// read_write_class_id 到 read_write_class 的映射
struct read_write_class {
    u32 owner_class_id;
    u64 class_ids_can_read_this[160];  // 系统最多支持 10240 个 class(BPF map 最大元素数)，160个 u64 刚好含 10240个比特
    u64 class_ids_can_write_this[160];
};
BPF_HASH(class_id_to_read_write_class, int, struct read_write_class);

// 全局配置
# define FLAG_RUNNING_ONCE 14
BPF_HASH(global_variable, u32, u32);

// ———————————— 主体状态库声明 ————————————
// 进程 PID 到 read_write_class_id 的映射
BPF_HASH(pid_to_read_write_class_id, u32, int);

// 进程 PID 的 read_write_class_id 和 dynamic_read_write_class_id
BPF_HASH(pid_to_dynamic_class_id, int, int);

// dynamic_read_write_class_id 到 dynamic_read_write_class 的映射
BPF_HASH(class_id_to_dynamic_read_write_class, int, struct read_write_class);

// 提取实体路径所用的缓存
BPF_PERCPU_ARRAY(filepath_cache, struct file_search_key, MAX_FOLDER_DEPTH);
// 防并行的锁
BPF_HASH(pid_to_spin_lock, int, u16);
// 为了dynamic_class_id分配
BPF_STACK(cpu0_free_dynamic_class_id, int, 10240);
BPF_STACK(cpu1_free_dynamic_class_id, int, 10240);
BPF_STACK(cpu2_free_dynamic_class_id, int, 10240);
BPF_STACK(cpu3_free_dynamic_class_id, int, 10240);


// ———————————— 与用户态程序交流所用的对象 ————————————
struct log_message{
    u64 message_id;
    char message[256];
};
BPF_RINGBUF_OUTPUT(log_output, 1 << 12);
BPF_PERCPU_ARRAY(log_message_cache, struct log_message, 1);
static void submit_Log(){
    int zero = 0;
    struct log_message* p_need_submit = log_message_cache.lookup(&zero);
    if (!p_need_submit) {
        return;
    }
    else{
        ++(p_need_submit->message_id);

    }
    log_output.ringbuf_output(p_need_submit, sizeof(*p_need_submit), 0);
}

struct class_modify_event{
    u64 db_update_event_id;
    int need_modify_class_id;
    int is_add;  // 为1时就将operand加入need_modify_class的R集合，为0时就删除
    int operand;
};
BPF_RINGBUF_OUTPUT(class_modify_event_sender, 1 << 10);
BPF_PERCPU_ARRAY(class_modify_event_cache, struct class_modify_event, 1);
static void submit_class_modify_event(){
    int zero = 0;
    struct class_modify_event* p_class_modify_event = class_modify_event_cache.lookup(&zero);
    if (!p_class_modify_event) {
        return;
    }
    else{
        p_class_modify_event->db_update_event_id += 1;
    }
    bpf_trace_printk("send:class_modify_event_sender");
    class_modify_event_sender.ringbuf_output(p_class_modify_event, sizeof(*p_class_modify_event), 0);
}


struct class_new_event_event{
    u64 db_update_event_id;
    char file_path[MAX_FOLDER_DEPTH][FILE_NAME_MAX];
    int Creator_class_id;
    int new_class_id;
};
BPF_RINGBUF_OUTPUT(class_new_event_sender, 1 << 12);
BPF_PERCPU_ARRAY(class_new_event_event_cache, struct class_new_event_event, 1);
static void submit_class_new_event_event(){
    int zero = 0;
    struct class_new_event_event* p_class_new_event_event = class_new_event_event_cache.lookup(&zero);

    if (!p_class_new_event_event) {
        return;
    }
    else{
        p_class_new_event_event->db_update_event_id += 1;
    }
    bpf_trace_printk("send:class_new_event_sender");
    class_new_event_sender.ringbuf_output(p_class_new_event_event, sizeof(*p_class_new_event_event), 0);

//    struct class_modify_event message_out = {};
//    message_out.db_update_event_id = 1;
//    message_out.need_modify_class_id = 2;
//    message_out.is_add = 3;
//    message_out.operand = 4;
//    class_modify_event_sender.ringbuf_output(&message_out, sizeof(message_out), 0);
}


struct class_delete_event{
    u64 db_update_event_id;
    char file_path[MAX_FOLDER_DEPTH][FILE_NAME_MAX];
};
BPF_RINGBUF_OUTPUT(class_delete_event_sender, 1 << 12);
BPF_PERCPU_ARRAY(class_delete_event_cache, struct class_delete_event, 1);
static void submit_class_delete_event(){
    int zero = 0;
    struct class_delete_event* p_class_delete_event = class_delete_event_cache.lookup(&zero);
    if (!p_class_delete_event) {
        return;
    }
    else{
        p_class_delete_event->db_update_event_id += 1;
    }
    bpf_trace_printk("send:class_delete_event_sender");
    class_delete_event_sender.ringbuf_output(p_class_delete_event, sizeof(*p_class_delete_event), 0);

//    struct class_modify_event message_out = {};
//    message_out.db_update_event_id = 1;
//    message_out.need_modify_class_id = 2;
//    message_out.is_add = 3;
//    message_out.operand = 4;
//    class_modify_event_sender.ringbuf_output(&message_out, sizeof(message_out), 0);
}



// ———————————— 一些主客体信息的函数 ————————————
static int get_bit_in_class_ids(int witch_bit,const u64 *big_list){
    int bit_in_witch_u64 = witch_bit >> 6;
    u64 witch_bit_need_output = 1 << (witch_bit & 0b111111);
    bit_in_witch_u64 = bit_in_witch_u64 & 0b111111;
    int ans = big_list[bit_in_witch_u64] & witch_bit_need_output;
    //bpf_trace_printk("ans:%d",ans);
    return ans;
}

static void set_bit_in_class_ids(int witch_bit, u64 *big_list, _Bool set_what){
    int bit_in_witch_u64 = witch_bit >> 6;
    u64 witch_bit_need_output = 1 << (witch_bit & 0b111111);
    bit_in_witch_u64 = bit_in_witch_u64 & 0b111111;
    if (set_what){
        big_list[bit_in_witch_u64] = big_list[bit_in_witch_u64] | witch_bit_need_output;
    }else{
        big_list[bit_in_witch_u64] = big_list[bit_in_witch_u64] & ~witch_bit_need_output;
    }
    //bpf_trace_printk("ans:%d",ans);
}

static int get_read_write_class_id_by_full_path(){
    _Bool path_start = 0;
    int read_where;
    struct file_search_key* p_file_name_cache;
    int i;
    for(i = 31;i > -1;i--){
        int p_now_name_need_read = i;
        p_file_name_cache = filepath_cache.lookup(&p_now_name_need_read);
        if(!p_file_name_cache)
            break;
        if(p_file_name_cache->raw_str[0] == '/')
            break;
    }
    int located_directory_id = 0;
    int out_put_read_write_class_id = 0;
    void* inner_map = 0;
    _Bool can_show_file_path = i>0;
    for(i = i - 1;i > -1;i--){
        // 1. 查外层 hash table
        int inner_map_key = located_directory_id & 0x7f;
        inner_map = parent_of_path_to_read_write_class_id.lookup(&inner_map_key);
        if (!inner_map)
            break;
        // 2. 查内层 hash table
        // 2.1. 构造内层 hash table 的键 (p_file_name_cache)
        int p_now_name_need_read = i;
        p_file_name_cache = filepath_cache.lookup(&p_now_name_need_read);
        if(!p_file_name_cache)
            break;
        //bpf_trace_printk("now we at:%s", p_file_name_cache->raw_str);

        p_file_name_cache->located_directory_id = located_directory_id;   // 完善 file_cashse (与2.1关系不大)
        //bpf_trace_printk("i read located_directory_id:%d", p_file_name_cache->located_directory_id);
        // 2.2. 查表
        struct file_search_value* now_file_info = bpf_map_lookup_elem(inner_map, p_file_name_cache);
        if (!now_file_info)
            break;
        // 3. 提取信息
        located_directory_id = now_file_info->my_id;
        out_put_read_write_class_id = now_file_info->my_read_write_class_id;
    }

    if(can_show_file_path){
        bpf_trace_printk("now we at:%s", p_file_name_cache->raw_str);
    }

    return out_put_read_write_class_id;
}

static int get_read_write_class_id_by_dentry(struct dentry * p_input){
    struct file_search_key* p_file_search_key;
    // 初始化 filepath_cache
    int write_where = 0;
    for(int i = 0;i<MAX_FOLDER_DEPTH;i++){
        p_file_search_key = filepath_cache.lookup(&write_where);
        if(!p_file_search_key)
            return 0;
        p_file_search_key->located_directory_id = 0;
        __builtin_memset(&p_file_search_key->raw_str,0, FILE_NAME_MAX);
        p_file_search_key->raw_str[0] = '\0';
        write_where += 1;
    }

    write_where = 0;
    struct dentry* now_dentry = p_input;
    struct qstr d_name;
    const unsigned char *name = 0;
    // 深度优先遍历 struct dentry * p_input
    for(int i = 0;i<MAX_FOLDER_DEPTH;i++){
        bpf_probe_read_kernel(&d_name, sizeof(d_name), (void *)&(now_dentry->d_name));
        name = d_name.name;
        if(!name)
            break;
        p_file_search_key = filepath_cache.lookup(&write_where);
        if(!p_file_search_key)
            return 0;
        bpf_probe_read_kernel_str(&p_file_search_key->raw_str, FILE_NAME_MAX, name);
        if (p_file_search_key->raw_str[0] == '/')
            break;
        write_where += 1;
        bpf_probe_read_kernel(&now_dentry, sizeof(now_dentry), (void *)&(now_dentry->d_parent));
    }
    return get_read_write_class_id_by_full_path();
}

static int get_read_write_class_id_by_file(struct file * p_input){
    if (!p_input)
        return 0;
    struct dentry * access_dentry = p_input->f_path.dentry;
    if (!access_dentry)
        return 0;
    return get_read_write_class_id_by_dentry(access_dentry);
}

static int get_read_write_class_id_by_bprm(struct linux_binprm * bprm){
    if (!bprm)
        return 0;
    return get_read_write_class_id_by_file(bprm->file);
}


static int get_read_write_class_id_by_msghdr(struct msghdr *msg_addr){
    struct sockaddr_in addr_in;
    struct sockaddr_in6 addr_in6;
    char ip[48];
    if (!msg_addr)
        return 0;

    if (msg_addr->msg_namelen == sizeof(struct sockaddr_in)) {
        bpf_probe_read(&addr_in, sizeof(addr_in), msg_addr->msg_name);

        bpf_probe_read_str(ip, 16, &addr_in.sin_addr);
        bpf_trace_printk("IPv4 Address: %s\n", ip);
    } else if (msg_addr->msg_namelen == sizeof(struct sockaddr_in6)) {
        bpf_probe_read(&addr_in6, sizeof(addr_in6), msg_addr->msg_name);
        bpf_probe_read_str(ip, 48, &addr_in6.sin6_addr);
        bpf_trace_printk("IPv6 Address: %s\n", ip);
    } else {
        bpf_trace_printk("Unknown address family\n");
    }
    return 0;
}
static int get_subject_inform(int* p_read_write_class_id, int* p_dynamic_class_id){
    if(!p_read_write_class_id || !p_dynamic_class_id)
        return 0;
    // 1. 获取进程（主体）的 read_write_class_id
    u64 tgid_pid = bpf_get_current_pid_tgid();
    u32 now_pid = (u32)(tgid_pid & 0xffffffff);
    int* p_tmp = pid_to_read_write_class_id.lookup(&now_pid);
    if (!p_tmp){
        *p_read_write_class_id = 0;
        return 0;
    }
    else
        *p_read_write_class_id = *p_tmp;
    // 2. 获取进程（主体）的 dynamic_read_write_class_id
    p_tmp = pid_to_dynamic_class_id.lookup(&now_pid);
    if (!p_tmp){
        *p_dynamic_class_id = 0;
        return 0;
    }
    else
        *p_dynamic_class_id = *p_tmp;
    return 1;
}


// ———————————— 用于修改数据的函数 ————————————
static int get_new_dynamic_read_write_class_id(){
    int ans = 0;
    u32 CPU_ID = bpf_get_smp_processor_id();
    switch(CPU_ID){
        case 0 :
            cpu0_free_dynamic_class_id.pop(&ans);
            break;
        case 1 :
            cpu1_free_dynamic_class_id.pop(&ans);
            break;
        case 2 :
            cpu2_free_dynamic_class_id.pop(&ans);
            break;
        case 3 :
            cpu3_free_dynamic_class_id.pop(&ans);
            break;
    }
    //int one = 1;
    //__sync_fetch_and_add (&ans, one);
    //bpf_trace_printk("CPU_ID: %d", CPU_ID);
    return ans;
}

static int release_dynamic_read_write_class_id(int id_input){
    unsigned int id_need_release = (unsigned int)id_input;
    u32 CPU_ID = id_need_release % 4;  // u32 CPU_ID = id_need_release % 4
    switch(CPU_ID){
        case 0 :
            cpu0_free_dynamic_class_id.push(&id_need_release, 0);
            break;
        case 1 :
            cpu1_free_dynamic_class_id.push(&id_need_release, 0);
            break;
        case 2 :
            cpu2_free_dynamic_class_id.push(&id_need_release, 0);
            break;
        case 3 :
            cpu3_free_dynamic_class_id.push(&id_need_release, 0);
            break;
    }
    return 1;
}

BPF_PERCPU_ARRAY(just_for_alloc_read_write_class, struct read_write_class, 1);
static struct read_write_class* alloc_read_write_class(){
    int zero = 0;
    return just_for_alloc_read_write_class.lookup(&zero);
}

BPF_ARRAY(just_for_alloc_read_write_class_id, int, 1);
BPF_PERCPU_ARRAY(just_for_count_alloc_read_write_class_id, int, 1);
static int alloc_new_read_write_class_id(){
    int zero = 0;
    int* p_new_read_write_class_id = just_for_alloc_read_write_class_id.lookup(&zero);
    int* p_alloc_count = just_for_count_alloc_read_write_class_id.lookup(&zero);

    if(!p_new_read_write_class_id || !p_alloc_count)
        return -1;
    int ans = *p_new_read_write_class_id  + *p_alloc_count * 4 + bpf_get_smp_processor_id();
    *p_alloc_count += 1;

    return ans;
}

BPF_ARRAY(just_for_alloc_file_id, int, 1);
BPF_PERCPU_ARRAY(just_for_count_alloc_file_id, int, 1);
static int alloc_new_file_id(){
    int zero = 0;
    int* p_new_read_write_class_id = just_for_alloc_file_id.lookup(&zero);
    int* p_alloc_count = just_for_count_alloc_file_id.lookup(&zero);

    if(!p_new_read_write_class_id || !p_alloc_count)
        return -1;
    int ans = *p_new_read_write_class_id  + *p_alloc_count * 4 + bpf_get_smp_processor_id();
    *p_alloc_count += 1;
    return ans;
}

// ———————————— 所有实体变动逻辑逻辑 ————————————
static int do_create(int creater_read_write_class_id, int creater_dynamic_read_write_class_id, struct dentry * new_file_dentry, int new_file_id){
    bpf_trace_printk("start do_create");
    // 1. 申请一个新的 read_write_class_id
    int new_read_write_class_id = alloc_new_read_write_class_id();
    if (new_read_write_class_id == -1)
        return 0;
    // 2. 查对应的 path_to_read_write_class_id
    get_read_write_class_id_by_dentry(new_file_dentry);
    int zero = 0;
    struct file_search_key* p_file_name_cache = filepath_cache.lookup(&zero);
    if(!p_file_name_cache)
        return 0;
    int inner_map_key = p_file_name_cache->located_directory_id & 0x7f;
    void* inner_map = parent_of_path_to_read_write_class_id.lookup(&inner_map_key);
    if (!inner_map)
        return 0;
    // 3. 在对应的 path_to_read_write_class_id 中添加一项
    struct file_search_value file_value_need_in = {};
    file_value_need_in.my_id = new_file_id;
    file_value_need_in.my_read_write_class_id = new_read_write_class_id;

    bpf_map_update_elem(inner_map, p_file_name_cache, &file_value_need_in, BPF_NOEXIST);
    // struct read_write_class* new_read_write_class = bpf_map_update_elem;
    // 4. 在 class_id_to_read_write_class 中添加一项
    struct read_write_class* new_read_write_class = alloc_read_write_class();
    if(!new_read_write_class)
        return 0;
    class_id_to_read_write_class.lookup_or_try_init(&new_read_write_class_id, new_read_write_class);
    // 5. 更新 new_read_write_class
    struct read_write_class* subject_class = class_id_to_dynamic_read_write_class.lookup(&creater_dynamic_read_write_class_id);
    new_read_write_class = class_id_to_read_write_class.lookup(&new_read_write_class_id);
    if(!new_read_write_class || !subject_class)
        return 0;
    new_read_write_class->owner_class_id = subject_class->owner_class_id;
    for(int i = 0;i<160;i++){
        new_read_write_class->class_ids_can_read_this[i] = subject_class->class_ids_can_read_this[i];
        new_read_write_class->class_ids_can_write_this[i] = subject_class->class_ids_can_write_this[i];
    }
    set_bit_in_class_ids(creater_read_write_class_id, new_read_write_class->class_ids_can_write_this, 1);
    // 5. 通知 python 后端
    struct class_new_event_event* p_class_new_event_event= class_new_event_event_cache.lookup(&zero);
    if(!p_class_new_event_event)
        return 0;
    for(int only_for_loop = 0;only_for_loop<MAX_FOLDER_DEPTH;only_for_loop++){
        int i = only_for_loop & 0b111111;

        __builtin_memset(&p_class_new_event_event->file_path[i], 0, FILE_NAME_MAX);
        p_file_name_cache = filepath_cache.lookup(&i);
        if(!p_file_name_cache)
            return 0;
        if(i<0 || i>31)
            return 0;
        bpf_probe_read_kernel_str(&p_class_new_event_event->file_path[i], FILE_NAME_MAX, p_file_name_cache->raw_str);
    }

    p_class_new_event_event->Creator_class_id = creater_read_write_class_id;
    p_class_new_event_event->new_class_id = new_read_write_class_id;

    submit_class_new_event_event();
    bpf_trace_printk("done do_create Creator_class_id:%d, new_class_id:%d",creater_read_write_class_id, new_read_write_class_id);
    return 0;
}

static int do_remove(struct dentry * remove_file_dentry){
    // 1. 获取信息
    get_read_write_class_id_by_dentry(remove_file_dentry);
    int zero = 0;
    struct file_search_key* p_file_name_cache = filepath_cache.lookup(&zero);
    if(!p_file_name_cache)
        return 0;
    // 2. 通知 python 后端
    struct class_delete_event* p_class_delete_event= class_delete_event_cache.lookup(&zero);
    if(!p_class_delete_event)
        return 0;
    for(int only_for_loop = 0;only_for_loop<MAX_FOLDER_DEPTH;only_for_loop++){
        int i = only_for_loop & 0b111111;

        __builtin_memset(&p_class_delete_event->file_path[i], 0, FILE_NAME_MAX);
        p_file_name_cache = filepath_cache.lookup(&i);
        if(!p_file_name_cache)
            return 0;
        if(i<0 || i>31)
            return 0;
        bpf_probe_read_kernel_str(&p_class_delete_event->file_path[i], FILE_NAME_MAX, p_file_name_cache->raw_str);
    }

    submit_class_delete_event();
    // 2. 修改主策略库 (删除 path_to_read_write_class_id 中的一个对应键值对)

    int inner_map_key = p_file_name_cache->located_directory_id & 0x7f;
    void* inner_map = parent_of_path_to_read_write_class_id.lookup(&inner_map_key);
    if (!inner_map)
        return 0;
    bpf_map_delete_elem(inner_map, p_file_name_cache);

    return 0;
}

// ———————————— 所有检查逻辑 ————————————
/**
 * @brief 检查进程读正常文件的判断逻辑 和 更新主体状态库
 * @param subject_id 主体的 read_write_class_id
 * @param object_id 客体的 read_write_class_id
 * @return 布尔值
 * 等于1时同意
 * 等于零时不同意
 * -1 时系统报错
 *
 * 检查逻辑如下：
 * 1. s ∈ R2
 * 2. (R1 ∩ R2) ⊇ Rs
 * 3. (W1 ∪ W2) ⊆ Ws
 * automatically relabelling s to (s, R1 ∩ R2, W1 ∪ W2)
 * 注意：在论文 SPLinux 中没有执行后两项检查
 */
static int entity_read_check(int subject_id, int object_id, int dynamic_class_id){
    bpf_trace_printk("start_entity_read_check   subject_id:%d, object_id:%d, dynamic_class_id:%d",
                     subject_id, object_id, dynamic_class_id);

    // 1. 检查是否合法
    struct read_write_class* subject_class = class_id_to_read_write_class.lookup(&subject_id);
    struct read_write_class* object_class = class_id_to_read_write_class.lookup(&object_id);
    struct read_write_class* dynamic_subject_class = class_id_to_dynamic_read_write_class.lookup(&dynamic_class_id);
    if(!subject_class||!object_class || !dynamic_subject_class){
        return -1;
    }

    // 1.1. s ∈ R2
    int bypass_condition1 = get_bit_in_class_ids(subject_id, object_class->class_ids_can_read_this);
    //bpf_trace_printk("bypass_condition1:%d",bypass_condition1);
    if (bypass_condition1 == 0){
        return 11;
    }

    // 1.2. (R1 ∩ R2) ⊇ Rs
    _Bool bypass_condition2 = 1;
    u64 tmp0;
    for(int for_loop = 0;for_loop < 160;for_loop++){
        int i = for_loop & 0b111111;
        tmp0 = subject_class->class_ids_can_read_this[i] & object_class->class_ids_can_read_this[i];
        if ((tmp0 | dynamic_subject_class->class_ids_can_read_this[i]) != tmp0){
            bypass_condition2 = 0;
        }
    }
    if (!bypass_condition2){
        //return 12;
    }
    // 1.3. (W1 ∪ W2) ⊆ Ws

    _Bool bypass_condition3 = 1;
    for(int for_loop = 0;for_loop < 160;for_loop++){
        int i = for_loop & 0b111111;
//        bpf_trace_printk("entity_read_check   subject:%d, object:%d, dynamic_class:%d",
//                     subject_class->class_ids_can_write_this[i],
//                     object_class->class_ids_can_write_this[i],
//                     dynamic_subject_class->class_ids_can_write_this[i]);
        tmp0 = subject_class->class_ids_can_write_this[i] | object_class->class_ids_can_write_this[i];
        if ((tmp0 | dynamic_subject_class->class_ids_can_write_this[i]) != dynamic_subject_class->class_ids_can_write_this[i]){
            bypass_condition3 = 0;
        }
    }
    if (!bypass_condition3){
        //return 13;
    }
    // 2. 若合法 更新主体状态库
    //automatically relabelling s to (s, R1 ∩ R2, W1 ∪ W2)
    for(int for_loop = 0;for_loop < 160;for_loop++){
        int i = for_loop & 0b111111;
        dynamic_subject_class->class_ids_can_read_this[i] = \
            subject_class->class_ids_can_read_this[i] & object_class->class_ids_can_read_this[i];
        dynamic_subject_class->class_ids_can_write_this[i] = \
            subject_class->class_ids_can_write_this[i] | object_class->class_ids_can_write_this[i];
    }
    return 1;
}

/**
 * @brief 检查进程写正常文件的判断逻辑
 * @param subject_id 主体的 read_write_class_id
 * @param object_id 客体的 read_write_class_id
 * @return 布尔值
 * 等于1时同意
 * 等于零时不同意
 * -1 时系统报错
 *
 * 检查逻辑如下：
 * 1. s ∈ W2
 * 2. R1 ⊇ R2
 * 3. W1 ⊆ W2
 */
static int entity_write_check(int subject_id, int object_id, int dynamic_class_id){
    bpf_trace_printk("start entity_write_check   subject_id:%d, object_id:%d, dynamic_class_id:%d",
                     subject_id, object_id, dynamic_class_id);

    struct read_write_class* subject_class = class_id_to_read_write_class.lookup(&subject_id);
    struct read_write_class* object_class = class_id_to_read_write_class.lookup(&object_id);
    struct read_write_class* dynamic_subject_class = class_id_to_dynamic_read_write_class.lookup(&dynamic_class_id);
    if(!subject_class||!object_class || !dynamic_subject_class){
        return -1;
    }

    // 1. s ∈ W2
    int bypass_condition1 = get_bit_in_class_ids(subject_id, object_class->class_ids_can_write_this);
    //bpf_trace_printk("bypass_condition1:%d",bypass_condition1);
    if (bypass_condition1 == 0){
        return 14;
    }

    // 2. R1 ⊇ R2
    _Bool bypass_condition2 = 1;
    u64 tmp0;
    for(int for_loop = 0;for_loop < 160;for_loop++){
        int i = for_loop & 0b111111;
        if ((dynamic_subject_class->class_ids_can_read_this[i] | object_class->class_ids_can_read_this[i]) != dynamic_subject_class->class_ids_can_read_this[i]){
            bypass_condition2 = 0;
        }
    }
    if (!bypass_condition2){
        return 15;
    }

    // 3. W1 ⊆ W2
    _Bool bypass_condition3 = 1;
    for(int for_loop = 0;for_loop < 160;for_loop++){
        int i = for_loop & 0b111111;
        if ((dynamic_subject_class->class_ids_can_write_this[i] | object_class->class_ids_can_write_this[i]) != object_class->class_ids_can_write_this[i]){
            bypass_condition3 = 0;
        }
    }
    if (!bypass_condition3){
        return 16;
    }
    return 1;
}


/**
 * @brief 检查进程降级文件的判断逻辑
 * @param subject_id 主体的 read_write_class_id
 * @param dynamic_class_id 主体的 dynamic_read_write_class_id
 * @param object_id 客体的 read_write_class_id
 * @param add_what_id 要加入到客体写集合的 read_write_class_id
 * @return 布尔值
 * 等于1时同意
 * 等于零时不同意
 * -1 时系统报错
 *
 * 检查逻辑如下：
 * 1. s = s1    -y
 * 2. s ∈ R2   -y
 * 3. s1 = s2   ignore
 * 4. W1 = W2   -y
 * 5. W2 = W3   ignore
 * 6. R1 = R2   -y
 * 7. R3 ⊇ R2   ignore
 * 8. W2 ⊇ (R3-R2)  转化为 add_what_id ∈ W2
 * downgrade an object o from (s1,R2,W2) to (s2, R3, W3)
 */
static int entity_downgrade_check(int subject_id, int dynamic_class_id, int object_id, int add_what_id){
    bpf_trace_printk("entity_downgrade_check start! subject_id:%d, object_id:%d, add_what_id:%d",
                     subject_id, object_id, add_what_id);

    // 1. 检查是否合法
    struct read_write_class *object_class = class_id_to_read_write_class.lookup(&object_id);
    struct read_write_class *dynamic_subject_class = class_id_to_dynamic_read_write_class.lookup(&dynamic_class_id);
    if (!dynamic_subject_class || !object_class || add_what_id <= 0)
    {
        return -1;
    }

    // 1.1. s = s1
    if (dynamic_subject_class->owner_class_id != object_class->owner_class_id)
    {
        bpf_trace_printk("filter_yang entity_downgrade_check: s=s1 failed dynamic_subject_class->owner_class_id:%d, object_class->owner_class_id:%d\n",
                         dynamic_subject_class->owner_class_id, object_class->owner_class_id);
        return 0;
    }
    // 1.2. s ∈ R2
    int bypass_condition = get_bit_in_class_ids(subject_id, object_class->class_ids_can_read_this);
    if (bypass_condition == 0)
    {
        bpf_trace_printk("filter_yang entity_downgrade_check: s belongs to R2 failed\n");
        return 0;
    }
    // 1.3. W1 = W2
    bypass_condition = 1;
    for (int i = 0; i < 160; i++)
    {
        if (dynamic_subject_class->class_ids_can_write_this[i] != object_class->class_ids_can_write_this[i])
        {
            bypass_condition = 0;
            break;
        }
    }
    if (bypass_condition == 0)
    {
        bpf_trace_printk("filter_yang entity_downgrade_check: W1=W2 failed\n");
        return 0;
    }
    // 1.4. R1 = R2
    for (int i = 0; i < 160; i++)
    {
        if (dynamic_subject_class->class_ids_can_read_this[i] != object_class->class_ids_can_read_this[i])
        {
            bypass_condition = 0;
            break;
        }
    }
    if (bypass_condition == 0)
    {
        bpf_trace_printk("filter_yang entity_downgrade_check: R1=R2 failed\n");
        return 0;
    }
    // 1.5. W2 ⊇ (R3-R2) 转化为 add_what_id ∈ W2
    bypass_condition = get_bit_in_class_ids(add_what_id, object_class->class_ids_can_write_this);
    if (bypass_condition == 0)
    {
        bpf_trace_printk("filter_yang entity_downgrade_check: add_what_id belongs to W2 failed\n");
        return 0;
    }

    return 1;
}

// ———————————— 所有预处理 ————————————
static int files_read_check(struct file *file)
{
    // 1. 获取进程（主体）的 read_write_class_id 和 dynamic_read_write_class_id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    //bpf_trace_printk("start_file_permission_read_check");

    // 2. 获取待访问文件的 read_write_class_id
    int object_read_write_class_id = get_read_write_class_id_by_file(file);
    if (object_read_write_class_id == 0){
        return 0;
    }
    // 3. 进行判断
    int check_ans = entity_read_check(subject_read_write_class_id, object_read_write_class_id,dynamic_read_write_class_id);

    bpf_trace_printk("file_permission_read_check: %d", check_ans);
    if(check_ans == 1){
        bpf_trace_printk("filter_yang files_read_check: file_read opration check passed\n");
    }else{
        bpf_trace_printk("filter_yang files_read_check: file_read opration check failed\n");
    }
    return check_ans;
}

static int files_write_check(struct file *file)
{

    // 1. 获取进程（主体）的 read_write_class_id 和 dynamic_read_write_class_id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    bpf_trace_printk("start_file_permission_write_check subject_read_write_class_id %d", subject_read_write_class_id);

    // 2. 获取待访问文件的 read_write_class_id
    int object_read_write_class_id = get_read_write_class_id_by_file(file);
    if (object_read_write_class_id == 0){
        return 0;
    }
    // 3. 进行判断
    int check_ans = entity_write_check(subject_read_write_class_id, object_read_write_class_id,dynamic_read_write_class_id);

    bpf_trace_printk("file_permission_write_check: %d", check_ans);
    if(check_ans == 1){
        bpf_trace_printk("filter_yang files_write_check: file_write opration check passed\n");
    }else{
        bpf_trace_printk("filter_yang files_write_check: file_write opration check failed\n");
    }
    return 0;
}

static int relabe_op(int need_change_class_id, _Bool is_add, int op_what_id){
    bpf_trace_printk("start relabe_op   need_change_class_id:%d, is_add:%d, op_what_id:%d",
                     need_change_class_id, is_add, op_what_id);
    /**
     * 检查逻辑如下：
     * 1. s = s1, s1 = s2
     * 2. s ∈ R2
     * 4. W1 = W2, W1 = W3
     * 5. s ∈ W3
     */
    // 1. 获取进程（主体）的 read_write_class_id 和 dynamic_read_write_class_id
    int subject_id = 0, dynamic_id = 0;
    get_subject_inform(&subject_id, &dynamic_id);
    if(subject_id==0 || dynamic_id==0)
        return -1;
    // 2. 检查是否合法
    struct read_write_class* subject_class = class_id_to_read_write_class.lookup(&subject_id);
    struct read_write_class* need_change_class = class_id_to_read_write_class.lookup(&need_change_class_id);
    //struct read_write_class* dynamic_subject_class = class_id_to_dynamic_read_write_class.lookup(&dynamic_id);
    //struct read_write_class* op_what_class = class_id_to_read_write_class.lookup(&op_what_id);
    if(!subject_class || !need_change_class){
        return -1;
    }
    // 2.1. s = s1, (s1 = s2)
    _Bool bypass_condition1 = (subject_id == need_change_class->owner_class_id);
    if (!bypass_condition1)
        return 21;
    // 2.2. s ∈ R2
    int bypass_condition2 = get_bit_in_class_ids(subject_id, need_change_class->class_ids_can_read_this);
    if (bypass_condition2 == 0){
        return 22;
    }
    // 2.4. W1 = W2, (W1 = W3)
    _Bool bypass_condition4 = 1;
    for(int for_loop = 0;for_loop < 160;for_loop++){
        int i = for_loop & 0b111111;
        if (subject_class->class_ids_can_write_this[i] != need_change_class->class_ids_can_write_this[i]){
            bypass_condition4 = 0;
        }
    }
    if (!bypass_condition4){
        return 24;
    }
    // 2.5. s ∈ W3 -> s ∈ W2
    int bypass_condition5 = get_bit_in_class_ids(subject_id, need_change_class->class_ids_can_write_this);
    if (bypass_condition5 == 0){
        return 25;
    }
    // 3. 若合法 更新客体状态库
    set_bit_in_class_ids(op_what_id, need_change_class->class_ids_can_read_this, 0);
    // 4. 通知 python 后端
    int zero = 0;
    struct class_modify_event* p_class_modify_event= class_modify_event_cache.lookup(&zero);
    if(!p_class_modify_event)
        return 0;
    // relabel 检查条件满足R2 ⊇ R3，is_add = 0 
    p_class_modify_event->is_add = 0;
    p_class_modify_event->need_modify_class_id = need_change_class_id;
    p_class_modify_event->operand = op_what_id;
    submit_class_modify_event();
    return 0;
}

static int downgrade_op(int need_change_class_id, int add_what_id){
    bpf_trace_printk("downgrade_op start!  need_change_class_id:%d, add_what_id:%d\n",
                     need_change_class_id, add_what_id);
                     
    if (need_change_class_id <= 0 || add_what_id <= 0)
    {
        bpf_trace_printk("downgrade_op: The need_change_class_id or add_what_id <= 0\n");
        return 0;
    }
    
    // 1. 获取进程（主体）的 read_write_class_id 和 dynamic_read_write_class_id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if (subject_read_write_class_id == 0 || dynamic_read_write_class_id == 0){
        bpf_trace_printk("downgrade_op: subject read_write_class_id or dynamic_read_write_class_id is 0, subject_read_write_class_id:%d, dynamic_read_write_class_id:%d\n",
         subject_read_write_class_id, dynamic_read_write_class_id);
        return 0;
    }
        
    // 2. 进行判断
    int check_ans = entity_downgrade_check(subject_read_write_class_id, dynamic_read_write_class_id, need_change_class_id, add_what_id);
    if (check_ans <= 0)
        return -1;

    // 3. 更新 need_change_class
    struct read_write_class *need_change_class = class_id_to_read_write_class.lookup(&need_change_class_id);
    if (!need_change_class)
    {
        bpf_trace_printk("downgrade_op: need_change_class is NULL\n");
        return 11;
    }
    set_bit_in_class_ids(add_what_id, need_change_class->class_ids_can_read_this, 1);

    // 4. 向后端发送消息
    int zero = 0;
    struct class_modify_event* p_class_modify_event_event= class_modify_event_cache.lookup(&zero);
    if(!p_class_modify_event_event){
        bpf_trace_printk("downgrade_op: p_class_modify_event_event is NULL\n");
        return -1;
    }
    
    p_class_modify_event_event->need_modify_class_id = need_change_class_id;
    p_class_modify_event_event->is_add = 1;
    p_class_modify_event_event->operand = add_what_id;
    submit_class_modify_event();
    return 0;
}

// ———————————— 所有挂载点 ————————————
// 主体调用exec
LSM_PROBE(bprm_creds_for_exec, struct linux_binprm * bprm)
{
    // 获取进程（主体）的 read_write_class_id
    int read_write_class_id = get_read_write_class_id_by_bprm(bprm);
    if (read_write_class_id == 0){
        return 0;
    }
    // 3. 更新 pid_to_read_write_class_id
    u64 tgid_pid = bpf_get_current_pid_tgid();
    u32 now_pid = (u32)(tgid_pid & 0xffffffff);
    pid_to_read_write_class_id.lookup_or_try_init(&now_pid,&read_write_class_id);
    pid_to_read_write_class_id.update(&now_pid,&read_write_class_id);
    // 4. 获取 dynamic_class_id
    int subject_read_write_class_id = 0, dynamic_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_class_id);
    // 5. 更新 class_id_to_dynamic_read_write_class
    struct read_write_class* dynamic_subject_class = class_id_to_dynamic_read_write_class.lookup(&dynamic_class_id);
    struct read_write_class* subject_class = class_id_to_read_write_class.lookup(&read_write_class_id);
    if(!subject_class || !dynamic_subject_class){
        return 0;
    }
    dynamic_subject_class->owner_class_id = subject_class->owner_class_id;
    // TODO 下面可能有问题
    bpf_probe_read_kernel(&dynamic_subject_class->class_ids_can_read_this,
                         sizeof(dynamic_subject_class->class_ids_can_read_this),
                         &subject_class->class_ids_can_read_this);
    bpf_probe_read_kernel(&dynamic_subject_class->class_ids_can_write_this,
                         sizeof(dynamic_subject_class->class_ids_can_write_this),
                         &subject_class->class_ids_can_write_this);

    bpf_trace_printk("bprm_creds_for_exec  success! pid:%d, class_id:%d, dynamic_class:%d", now_pid, read_write_class_id, dynamic_class_id);

    return 0;
}

// fork
TRACEPOINT_PROBE(task, task_newtask) {
    // args is from /sys/kernel/debug/tracing/events/task/task_newtask
    //bpf_trace_printk("new process PID: %d", args->pid);
    // 获取 父进程 和 子进程 的 pid
    u64 tgid_pid = bpf_get_current_pid_tgid();
    u32 parent_pid = (u32)(tgid_pid & 0xffffffff);
    u32 subprocess_pid = args->pid;
    // 获取 父进程 和 子进程 的 read_write_class_id
    int* tmp0 = pid_to_read_write_class_id.lookup(&parent_pid);
    if(!tmp0)
        return 0;
    int parent_read_write_class_id = *tmp0;
    tmp0 = pid_to_dynamic_class_id.lookup(&parent_pid);
    if(!tmp0)
        return 0;
    int parent_dynamic_read_write_class_id = *tmp0;

    int subprocess_dynamic_read_write_class_id = get_new_dynamic_read_write_class_id();

    // 3. 向 pid_to_read_write_class_id 中新加一项
    u32 now_pid = (u32)(subprocess_pid & 0xffffffff);
    pid_to_read_write_class_id.lookup_or_try_init(&now_pid,&parent_read_write_class_id);
    pid_to_read_write_class_id.update(&now_pid,&parent_read_write_class_id);
    // 4. 向 pid_to_dynamic_class_id 中新加一项
    pid_to_dynamic_class_id.lookup_or_try_init(&now_pid, &subprocess_dynamic_read_write_class_id);
    pid_to_dynamic_class_id.update(&now_pid, &subprocess_dynamic_read_write_class_id);
    // 5. 复制 class_id_to_dynamic_read_write_class
    struct read_write_class* dynamic_sub_class = class_id_to_dynamic_read_write_class.lookup(&subprocess_dynamic_read_write_class_id);
    struct read_write_class* dynamic_parent_class = class_id_to_dynamic_read_write_class.lookup(&parent_dynamic_read_write_class_id);
    if(!dynamic_sub_class || !dynamic_parent_class){
        return 0;
    }
    dynamic_sub_class->owner_class_id = dynamic_parent_class->owner_class_id;
    bpf_probe_read_kernel(&dynamic_sub_class->class_ids_can_read_this,
                         sizeof(dynamic_sub_class->class_ids_can_read_this),
                         &dynamic_parent_class->class_ids_can_read_this);
    bpf_probe_read_kernel(&dynamic_sub_class->class_ids_can_write_this,
                         sizeof(dynamic_sub_class->class_ids_can_write_this),
                         &dynamic_parent_class->class_ids_can_write_this);

    bpf_trace_printk("task_newtask:fork  success!");
    return 0;
}

// exit 进程退出，主体退出
LSM_PROBE(task_free, struct task_struct *task)
{
    // 1. 求退出进程的pid
    int free_pid = 0;
    bpf_probe_read_kernel(&free_pid, sizeof(free_pid), &task->pid);
    // 2. 在 class_id_to_dynamic_read_write_class 中删去一项
    int* p_dynamic_class_id_need_free = pid_to_dynamic_class_id.lookup(&free_pid);
    int dynamic_class_id_need_free = -1;
    if (p_dynamic_class_id_need_free){
        dynamic_class_id_need_free = *p_dynamic_class_id_need_free;
        class_id_to_dynamic_read_write_class.delete(p_dynamic_class_id_need_free);
    }
    // 3. 在 pid_to_dynamic_class_id 中删去一项
    pid_to_dynamic_class_id.delete(&free_pid);
    // 4.回收 dynamic_class_id
    if (dynamic_class_id_need_free != -1){
        release_dynamic_read_write_class_id(dynamic_class_id_need_free);

    }
    return 0;
}

// 主体读写文件
LSM_PROBE(file_permission, struct file *file, int mask)
{
    char task_name[16];
    bpf_get_current_comm(task_name, sizeof(task_name));
    char ok_name[16] = "test_sub_worker";
    if (task_name[0] != 't' || task_name[1] != 'e') {
        return 0;
    }
    bpf_trace_printk("start_file_permission_mask %s %d", task_name, mask);

    int final_conclusion = 0;
    if ((MAY_READ & mask) > 0)
        if (files_read_check(file) != 1)
            final_conclusion = 1;
    if ((MAY_WRITE & mask) > 0)
        if (files_write_check(file) != 1)
            final_conclusion = 1;

    bpf_trace_printk("end_file_permission_mask %s %d", task_name, mask);

    #if IS_DEBUG != 1
    return final_conclusion;
    #endif


    return 0;
}

/**
 * @brief 接受主体的新建客体请求，修改内核中的主策略库，通知python后端同步修改
 * @param 与LSM钩子 security_inode_create 保持一致
 * @return 0
 */
LSM_PROBE(inode_create, struct inode *dir, struct dentry *dentry, umode_t mode){
    bpf_trace_printk("start inode_create");
    // 1. 判断是否有权新建文件
    // 1.1. 获得新建文件所在目录的 rwclass id
    struct dentry *parent_directory_dentry = dentry->d_parent;
    int parent_read_write_class_id = get_read_write_class_id_by_dentry(parent_directory_dentry);
    if(parent_read_write_class_id ==0)
        return 0;
    // 1.2. 获得进程的两个 rwclass id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 1.3. 调用 entity_write_check
    int check_ans = entity_write_check(subject_read_write_class_id,
                                       parent_read_write_class_id,
                                       dynamic_read_write_class_id);
    bpf_trace_printk("inode_create: check_ans: %d", check_ans);
    if (check_ans != 1)
        bpf_trace_printk("filter_yang inode_create: new opration check failed\n");
    else
        bpf_trace_printk("filter_yang inode_create: new opration check passed\n");
    #if IS_DEBUG != 1
    if (check_ans != 1){
        return 1;
    }
    #endif

    do_create(subject_read_write_class_id, dynamic_read_write_class_id, dentry, -1);
    return 0;
}

/**
 * @brief 接受主体的新建目录请求，修改内核中的主策略库，通知python后端同步修改
 * @param 与LSM钩子 security_inode_mkdir 保持一致
 * @return 0
 */
LSM_PROBE(inode_mkdir, struct inode *dir, struct dentry *dentry, umode_t mode){
    bpf_trace_printk("start inode_mkdir");
    // 1. 判断是否有权新建文件
    // 1.1. 获得新建文件所在目录的 rwclass id
    struct dentry *parent_directory_dentry = dentry->d_parent;
    int parent_read_write_class_id = get_read_write_class_id_by_dentry(parent_directory_dentry);
    if(parent_read_write_class_id ==0)
        return 0;
    // 1.2. 获得进程的两个 rwclass id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 1.3. 调用 entity_write_check
    int check_ans = entity_write_check(subject_read_write_class_id,
                                       parent_read_write_class_id,
                                       dynamic_read_write_class_id);
    #if IS_DEBUG != 1
    if (check_ans != 1){
        return 1;
    }
    #endif

    do_create(subject_read_write_class_id, dynamic_read_write_class_id,dentry, alloc_new_file_id());

    return 0;
}

/**
 * @brief 接受主体的删除客体请求，修改内核中的主策略库，通知python后端同步修改
 * @param 与LSM钩子 security_inode_unlink 保持一致
 * @return 0
 */
LSM_PROBE(inode_unlink, struct inode *dir, struct dentry *dentry){
    bpf_trace_printk("start inode_unlink");
    // 1. 判断是否有权新建文件
    // 1.1. 获得新建文件所在目录的 rwclass id
    struct dentry *parent_directory_dentry = dentry->d_parent;
    int parent_read_write_class_id = get_read_write_class_id_by_dentry(parent_directory_dentry);
    if(parent_read_write_class_id ==0)
        return 0;
    // 1.2. 获得进程的两个 rwclass id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 1.3. 调用 entity_write_check
    int check_ans = entity_write_check(subject_read_write_class_id,
                                       parent_read_write_class_id,
                                       dynamic_read_write_class_id);
    if (check_ans != 1)
        bpf_trace_printk("filter_yang inode_unlink: remove opration check failed\n");
    else
        bpf_trace_printk("filter_yang inode_unlink: remove opration check passed\n");
    #if IS_DEBUG != 1
    if (check_ans != 1){
        return 1;
    }
    #endif
    do_remove(dentry);
    return 0;
}

/**
 * @brief 接受主体的删除目录请求，修改内核中的主策略库，通知python后端同步修改
 * @param 与LSM钩子 security_inode_rmdir 保持一致
 * @return 0
 */
LSM_PROBE(inode_rmdir, struct inode *dir, struct dentry *dentry){
    bpf_trace_printk("start inode_rmdir");
    // 1. 判断是否有权新建文件
    // 1.1. 获得新建文件所在目录的 rwclass id
    struct dentry *parent_directory_dentry = dentry->d_parent;
    int parent_read_write_class_id = get_read_write_class_id_by_dentry(parent_directory_dentry);
    if(parent_read_write_class_id ==0)
        return 0;
    // 1.2. 获得进程的两个 rwclass id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 1.3. 调用 entity_write_check
    int check_ans = entity_write_check(subject_read_write_class_id,
                                       parent_read_write_class_id,
                                       dynamic_read_write_class_id);

    #if IS_DEBUG != 1
    if (check_ans != 1){
        return 1;
    }
    #endif
    do_remove(dentry);
    return 0;
}

/**
 * @brief 新建特殊文件，如 FIFO、socket等
 * @param
 * @return 0
 */
LSM_PROBE(inode_mknod, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev){
    if (!S_ISFIFO(mode))
        return 0;
    bpf_trace_printk("start inode_mknod");
    // 1. 判断是否有权新建文件
    // 1.1. 获得新建文件所在目录的 rwclass id
    struct dentry *parent_directory_dentry = dentry->d_parent;
    int parent_read_write_class_id = get_read_write_class_id_by_dentry(parent_directory_dentry);
    if(parent_read_write_class_id ==0)
        return 0;
    // 1.2. 获得进程的两个 rwclass id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 1.3. 调用 entity_write_check
    int check_ans = entity_write_check(subject_read_write_class_id,
                                       parent_read_write_class_id,
                                       dynamic_read_write_class_id);
    #if IS_DEBUG != 1
    if (check_ans != 1){
        return 1;
    }
    #endif

    do_create(subject_read_write_class_id, dynamic_read_write_class_id, dentry, -1);
    return 0;
}

/**
 * @brief 网络发送数据
 * @param
 * @return 0
 */
LSM_PROBE(socket_sendmsg, struct socket *sock, struct msghdr *msg, int size){
    // 1. 获取进程（主体）的 read_write_class_id 和 dynamic_read_write_class_id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 2. 获取 发送者 的 read_write_class_id
    int object_read_write_class_id = get_read_write_class_id_by_msghdr(msg);
    if (object_read_write_class_id == 0){
        return 0;
    }
    // 3. 进行判断
    int check_ans = entity_write_check(subject_read_write_class_id, object_read_write_class_id, dynamic_read_write_class_id);

    bpf_trace_printk("socket_sendmsg_check: %d", check_ans);

    #if IS_DEBUG != 1
    if (check_ans != 1)
        return 1;
    #endif

    return 0;
}

/**
 * @brief 网络接受数据
 * @param
 * @return 0
 */
LSM_PROBE(socket_recvmsg, struct socket *sock, struct msghdr *msg, int size, int flags){
    // 1. 获取进程（主体）的 read_write_class_id 和 dynamic_read_write_class_id
    int subject_read_write_class_id = 0, dynamic_read_write_class_id = 0;
    get_subject_inform(&subject_read_write_class_id, &dynamic_read_write_class_id);
    if(subject_read_write_class_id==0 || dynamic_read_write_class_id==0)
        return 0;
    // 2. 获取 发送者 的 read_write_class_id
    int object_read_write_class_id = get_read_write_class_id_by_msghdr(msg);
    if (object_read_write_class_id == 0){
        return 0;
    }
    // 3. 进行判断
    int check_ans = entity_read_check(subject_read_write_class_id, object_read_write_class_id, dynamic_read_write_class_id);

    bpf_trace_printk("socket_recvmsg_check: %d", check_ans);

    #if IS_DEBUG != 1
    if (check_ans != 1)
        return 1;
    #endif

    return 0;
}


int trace_sys_enter(struct sys_enter_args *args)
{

    int syscall_num = args->id;
    // bpf_trace_printk("Hello, now sys%d enter ", syscall_num);
    if (syscall_num == 1){
        if(args->args[0] == RELABLE_SYSCALL_NUM){
            bpf_trace_printk("Hello, now relabe enter");
            int check_ans = relabe_op(args->args[1], args->args[2] == 1, args->args[3]);
            if(check_ans == 0){
                bpf_trace_printk("filter_yang relabe: relabe opration check passed\n");
            }else{
                bpf_trace_printk("filter_yang relabe: relabe opration check failed\n");
            }
        }
        else if(args->args[0] == DOWNGRADE_SYSCALL_NUM){
            bpf_trace_printk("Hello, now downgrade enter");
            int check_ans = downgrade_op(args->args[1], args->args[2]);
            if(check_ans == 0){
                bpf_trace_printk("filter_yang downgrad: downgrad opration check passed\n");
            }else{
                bpf_trace_printk("filter_yang downgrad: downgrad opration check failed\n");
            }
        }
    }

    return 0;
}

